<template>
  <transition name="fade-scale">
    <div
      v-if="visible"
      class="quick-search"
      :style="{
        left: x + 'px',
        top: y + 'px',
      }"
      @keydown.stop
    >
      <div class="qs-input-wrap">
        <span class="qs-icon">🔍</span>
        <input
          ref="inputRef"
          v-model="keyword"
          class="qs-input"
          type="text"
          placeholder="搜索节点...（Esc 关闭）"
          @keydown.enter="enterFirst"
          @keydown.esc.prevent.stop="close"
        />
      </div>

      <div class="qs-list" role="listbox">
        <div
          v-for="n in filtered"
          :key="n.type"
          class="qs-item"
          role="option"
          tabindex="0"
          @click="select(n)"
        >
          <span class="qs-dot">•</span>
          <span class="qs-label">{{ n.label }}</span>
          <span class="qs-type">{{ n.type }}</span>
        </div>
        <div v-if="filtered.length === 0" class="qs-empty">无匹配节点</div>
      </div>
    </div>
  </transition>
</template>

<script setup lang="ts">
import { ref, watch, computed, onMounted, nextTick } from "vue";

const props = defineProps<{
  visible: boolean;
  x: number;
  y: number;
}>();

const emit = defineEmits<{
  (e: "close"): void;
  (
    e: "node-select",
    node: { type: string; label: string; category?: string }
  ): void;
}>();

const inputRef = ref<HTMLInputElement | null>(null);
const keyword = ref("");

// 快速添加节点源（携带分类）
const allNodes = [
  { type: "form", label: "人工节点", category: "form" },
  { type: "auto", label: "自动化节点", category: "auto" },
  { type: "approval", label: "审批节点", category: "approval" },
  { type: "custom", label: "自定义节点", category: "custom" },
  { type: "condition", label: "条件节点", category: "condition" },
  { type: "control", label: "控制节点", category: "control" },
];

const filtered = computed(() => {
  if (!keyword.value) return allNodes;
  return allNodes.filter(
    (n) => n.label.includes(keyword.value) || n.type.includes(keyword.value)
  );
});

function select(n: { type: string; label: string; category?: string }) {
  emit("node-select", n);
}

function close() {
  emit("close");
}

function enterFirst() {
  if (filtered.value.length > 0) select(filtered.value[0]);
}

// 聚焦处理：每次打开都聚焦输入框
watch(
  () => props.visible,
  async (v) => {
    if (v) {
      keyword.value = "";
      await nextTick();
      inputRef.value?.focus();
    }
  },
  { immediate: true }
);

// 点击外部关闭（简单委托，由父容器可再增强）
onMounted(() => {
  const onDocClick = (e: MouseEvent) => {
    // 若面板已关闭直接忽略
    if (!props.visible) return;
    const el = (e.target as HTMLElement).closest(".quick-search");
    if (!el) close();
  };
  document.addEventListener("mousedown", onDocClick);
});
</script>

<style scoped>
.quick-search {
  position: fixed; /* 使用 viewport 坐标，传入 clientX/Y 即可 */
  z-index: 4000;
  width: 280px;
  max-height: 320px;
  background: var(--color-bg-2, #fff);
  border: 1px solid var(--color-border-2, #e5e7eb);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: 10px;
}
.qs-input-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
}
.qs-icon {
  color: #94a3b8;
}
.qs-input {
  flex: 1;
  height: 30px;
  border: 1px solid var(--color-border-2, #e5e7eb);
  border-radius: 6px;
  padding: 0 8px;
  outline: none;
}
.qs-list {
  margin-top: 8px;
  max-height: 250px;
  overflow: auto;
}
.qs-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 6px;
  border-radius: 6px;
  cursor: pointer;
}
.qs-item:hover {
  background: var(--color-fill-2, #f3f4f6);
}
.qs-dot {
  color: #10b981;
}
.qs-label {
  flex: 1;
}
.qs-type {
  color: #94a3b8;
  font-size: 12px;
}
.qs-empty {
  color: #94a3b8;
  text-align: center;
  padding: 16px 0;
}

.fade-scale-enter-active,
.fade-scale-leave-active {
  transition: all 0.12s ease;
}
.fade-scale-enter-from,
.fade-scale-leave-to {
  opacity: 0;
  transform: scale(0.98);
}
</style>
